package com.chapter17.demo6;


/**
 * sychronized关键字的另一种用法是用来修饰方法，被修饰的方法称为同步方法，是线程安全的，不会出现并发访问的问题。
 *
 * 同步方法和同步语句块的实现原理是一样的，都是对某个对象的监视器进行加锁和解锁，
 * 同步方法使用的是this代表的对象的监视器。在本例中，就是SellTicketTask对象。
 * 要注意，本例不能直接在run方法上添加synchronized关键字，因为run方法中是一个循环，
 * 当一个线程访问run方法时，得到this对象的锁，进入循环，当循环结束，run方法执行完毕，锁才会被释放。
 * 而循环都结束了，票也卖光了，相当于一个线程卖了所有的票，多线程程序变成了单线程程序，
 */
public class SellTicketTask implements Runnable{
   private int tickets =100;

    @Override
    public void run() {
        while (tickets>0){
            sell();
        }
    }

    private synchronized void sell(){
        if(tickets>0){
            System.out.printf("%s sell tickets: %d%n",Thread.currentThread().getName(),tickets);
            tickets --;
        }
    }
}
